function [schidx,nsidx] = ThresholdTrackSelectFcn(sch,schidx)
% [schidx,nsidx] = ThresholdTrackSelectFcn(sch,schidx)
%
%  Select the next trial index (NSIDX) based on previous responses. Once
%  NumReversals is met then moves on to next frequency.
%
%  Use the following parameters in schedule.writeparams including *
%  ('Write' or 'Read/Write' functionality in ScheduleMaker):
% 
%       *FreqList  ... list of frequencies to test

%  Takes the schedule and schidx as input.
%       SCH is the schedule structure
%       SCHIDX is a 1D matrix with the number of rows equal to the number
%           of unique trials; i.e. size(trials,1).
%  Returns an updated version of SCHIDX and NSIDX
%       NSIDX is the next schedule trial index, i.e. the next index
%           selected from the SCH.trials matrix to run.
%       SCHIDX should be updated with the number of runs for each unique
%           trial in SCH.trials.  The returned version should have
%           SCHIDX(NSIDX) incremented.
%
%  This same format for input and output paramters must be met for custom
%  trial select functions (i.e., experiment.trialselectfcn);
%
%  DJS (c) 2011

global G_RP

% persistent TR % tracking

% some constants
START_LEVEL = 70;
HIGH_LEVEL  = 100;
LOW_LEVEL   = -20;
DOWN_STEP   = -10;
UP_STEP     = 10;
NUM_REV     = 10;

CATCH_P     = 0.0; % probability of catch trial
CATCH_RR    = 1.0; % probability of reinforcing catch trial

if ~isfield(sch,'trial_idx'), sch.trial_idx = 1; end
trials = sch.trials;
boxid  = sch.boxid;
RV = sch.response_vals;

% find soem paramters
fridx = findincell(strfind(sch.writeparams,'FreqList'));
cbidx = findincell(strfind(sch.writeparams,'ToneCalibration'));
cpidx = findincell(strfind(sch.writeparams,'CATCH_P'));
cridx = findincell(strfind(sch.writeparams,'CATCH_RR'));
lvidx = findincell(strfind(sch.readparams,'ToneDB'))+1;
rvidx = findincell(strfind(sch.readparams,'response_code'))+1;
ttidx = findincell(strfind(sch.readparams,'trial_type'))+1;

if ~isempty(cpidx)
    CATCH_P = cell2mat(trials(1,cpidx));
end

if ~isempty(cridx)
    CATCH_RR = cell2mat(trials(1,cridx));
end

flist = cell2mat(trials(:,fridx));
clist = cell2mat(trials(:,cbidx));

% which module?
writemod = sch.writemodule(fridx);
RP = G_RP(writemod);

% initialize first trial
if isempty(RV)
    schidx = zeros(size(trials,1),1); % initialize SCHIDX
    nsidx = 1;
    schidx(nsidx) = 1;
    
    RP.SetTagVal(sprintf('trial_type~%d',boxid),0);
    RP.SetTagVal(sprintf('ToneFreq~%d',boxid),flist(1));
    RP.SetTagVal(sprintf('ToneCalibration~%d',boxid),clist(1));
    RP.SetTagVal(sprintf('ToneDB~%d', boxid),START_LEVEL);
    return
end

% Test if catch trial
tt = rand(1) < CATCH_P;
RP.SetTagVal(sprintf('trial_type~%d',boxid),tt);

if tt % if catch trial, then reward with CATCH_RR probability
    ttp = single(rand <= CATCH_RR);
    e = RP.SetTagVal(sprintf('Reward~%d',boxid),ttp);
else
    ttp = 1;
    e = RP.SetTagVal(sprintf('Reward~%d',boxid),ttp);
end
% fprintf('Tag: "Reward~%d", val = %d, syccess = %d\n', ...
%     boxid,RP.GetTagVal(sprintf('Reward~%d',boxid)),e)

TR = 0;

% which frequency was just presented
tf = RP.GetTagVal(sprintf('ToneFreq~%d',boxid));
nsidx = find(flist==tf);

if ~tt && size(RV,1) > 1 &&RV(end,ttidx) == 0
    rp = sch.readparams;
    %     ttypidx = findincell(strfind(rp,'trial_type'))+1;
    levlidx = findincell(strfind(rp,'ToneDB'))+1;
    freqidx = findincell(strfind(rp,'ToneFreq'))+1;
    
    ind = RV(:,freqidx) == tf;
    level = RV(ind,levlidx);
    
    k = 1;
    revlevel = 0;
    if numel(level) > 1
        lastdir = level(2) > level(1); % up: 1 , down: 0
        for j = 2:length(level)
            if lastdir && level(j) < level(j-1) ...
                    || ~lastdir && level(j) > level(j-1)
                revlevel(k) = level(j-1); %#ok<AGROW>
                %             revidx(k)   = j-1;
                lastdir = ~lastdir;
                k = k + 1;
            end
        end
    end
    TR = numel(revlevel);
    lastidx = find(~RV(:,ttidx),1,'last');   
    oneback = bitget(RV(lastidx,rvidx),6);
    
%         lastidx = find(~RV(1:lastidx-1,ttidx),1,'last');
%         if isempty(lastidx)
%             twoback = oneback;
%         else
%             twoback = bitget(RV(lastidx,rvidx),6);
%         end
%         
%         % track reversals
%         TR(boxid) = TR(boxid) + xor(oneback,twoback);
        
end



SL = RV(end,lvidx);

if TR == NUM_REV % move on to next frequency
    nsidx = nsidx + 1; % go to next frequency
    if nsidx > length(flist), nsidx = 1; end
    RP.SetTagVal(sprintf('ToneFreq~%d',boxid),flist(nsidx));
    RP.SetTagVal(sprintf('ToneCalibration~%d',boxid),clist(nsidx));
    
    % use threshold from previous frequency to start next frequency
    SL = RV(end,lvidx) + UP_STEP;
    
elseif ~tt && exist('oneback','var')
    % adjust sound level for next trial
    if oneback % last trial was a hit, so decrease sound level
        SL = SL - abs(DOWN_STEP);
    else % missed the last stimulus, so increase sound level
        SL = SL + UP_STEP;
    end
end

% respect bounds
if SL > HIGH_LEVEL, SL = HIGH_LEVEL; end
if SL < LOW_LEVEL,  SL = LOW_LEVEL;  end

% Update RPvds Tags
RP.SetTagVal(sprintf('ToneDB~%d', boxid),SL);

% update SCHIDX
schidx(nsidx) = schidx(nsidx) + 1;









